package cn.bonoon.kernel.web.handlers;

import java.lang.reflect.Constructor;

import cn.bonoon.handler.impl.StandardAutoManager;
import cn.bonoon.kernel.events.OperateEvent;
import cn.bonoon.kernel.support.OperandSupport;
import cn.bonoon.kernel.support.entities.Persistable;
import cn.bonoon.kernel.support.models.ObjectEditor;
import cn.bonoon.kernel.support.services.GenericService;
import cn.bonoon.kernel.web.ButtonEventType;
import cn.bonoon.kernel.web.ButtonRefreshType;
import cn.bonoon.kernel.web.controllers.FormButtonResolver;
import cn.bonoon.kernel.web.controllers.IFormHandler;

/**
 * <pre>
 * 主要用于提交表单
 * </pre>
 * @author jackson
 *
 * @param <E>
 */
public abstract class AbstractOperateFormHandler<E extends Persistable> extends AbstractOperateHandler implements IFormHandler, OperandSupport{
	protected final Class<?> editClass;
	protected final GenericService<E> service;
	protected final Constructor<?> constructor;
	protected final StandardAutoManager initializer;
	
	private String defaultFunctionName;

	public AbstractOperateFormHandler(int operand, GenericService<E> service, StandardAutoManager initializer, Class<?> editClass)throws Exception{
		super(operand, OPERAND_NAMES[operand], initializer);
		this.service = service;
		this.editClass = editClass;
		this.initializer = initializer;
		this.constructor = editClass.getConstructor();
		
	}

	@Override
	protected final Object internalExecute(OperateEvent event) throws Exception{
		return internalExecute(event, (ObjectEditor)event.getSource());
	}
	
	protected abstract Object internalExecute(OperateEvent event, ObjectEditor editor) throws Exception;
	
	public Object buildParams() {
		try {
			return constructor.newInstance();
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * <pre>
	 * 对按钮的事件进行注册，该方法默认将会对
	 * 刷新方式{@link FormButtonResolver#setRefreshType(ButtonRefreshType)}进行赋值，默认值为：{@link ButtonRefreshType.FINISH}
	 * 处理事件{@link FormButtonResolver#setEventType(ButtonEventType)}进行赋值，默认值为：{@link ButtonEventType.FORM}
	 * 
	 * 如果子类需要全貌和其它的属性的，可以重写该方法覆盖这些默认值
	 * </pre>
	 * @param buttonResolver
	 * @return
	 */
	public FormButtonResolver register(FormButtonResolver buttonResolver){
		buttonResolver.setKey(operandCode);
		buttonResolver.setName(operateName);
		initializer.register(this);
		buttonResolver.setUrl(getUrl());
		buttonResolver.setRefreshType(ButtonRefreshType.FINISH);
		buttonResolver.setEventType(ButtonEventType.FORM);
		buttonResolver.setFunctionName(defaultFunctionName);
		return buttonResolver;
	}

	public String getDefaultFunctionName() {
		return defaultFunctionName;
	}

	public void setDefaultFunctionName(String defaultFunctionName) {
		this.defaultFunctionName = defaultFunctionName;
	}
	
	public Class<?> getEditClass() {
		return editClass;
	}
	
	public GenericService<E> getService() {
		return service;
	}
}
